package com.zhou.spring.cloud.balancer;

import com.zhou.common.operator.log.core.annotation.OperateLog;
import com.zhou.common.operator.log.core.constant.OperateActionEnum;
import com.zhou.spring.cloud.balancer.config.MyLoadBalancerClientsConfiguration;
import com.zhou.spring.cloud.balancer.feign.TestFegin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.support.HttpRequestWrapper;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
//@EnableFeignClients(defaultConfiguration = {CustomFeignConfiguration.class})
@EnableFeignClients
@LoadBalancerClients(defaultConfiguration = {MyLoadBalancerClientsConfiguration.class})
public class BalancerApplication {
    public static void main(String[] args) {
        SpringApplication.run(BalancerApplication.class, args);
    }

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        builder = builder.defaultHeader("zone", "xi");
        return builder.build();
    }

    @RestController
    public class TestController {

        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }

        @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
            return restTemplate.getForObject("http://cloud-server/test/retry/" + str, String.class);
        }

        @Autowired
        private TestFegin testFegin;

        @OperateLog(action = OperateActionEnum.OPERATION,
                operateInstruction = "测试日志组件",
                operateSystem = "operateSystem",
                operateType = "operateType",
                operateModule = "operateModule"
        )
        @RequestMapping(value = "/echo1/{str}", method = RequestMethod.GET)
        public String echo1(@PathVariable String str) {
            return testFegin.echo(str);
        }

        @RequestMapping(value = "/temeout", method = RequestMethod.GET)
        public String temeout() {
            return testFegin.testtTimout();
        }

        @RequestMapping(value = "/testException", method = RequestMethod.GET)
        public String testException() {
            return testFegin.testException();
        }
    }

    //只能做全局
    @Bean
    public LoadBalancerRequestTransformer transformer() {
        return new LoadBalancerRequestTransformer() {
            @Override
            public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) {
                return new HttpRequestWrapper(request) {
                    @Override
                    public HttpHeaders getHeaders() {
                        HttpHeaders headers = new HttpHeaders();
                        headers.putAll(super.getHeaders());
                        headers.add("X-InstanceId", instance.getInstanceId());
                        return headers;
                    }
                };
            }
        };
    }

//    @Bean
//    public OkHttpClient getOkHttpClient() {
//        return new OkHttpClient.Builder()
//                .connectTimeout(1, TimeUnit.SECONDS)
//                .readTimeout(5, TimeUnit.SECONDS)
//                .followRedirects(false)
//                .build();
//    }

}
